package main

import (
	"crypto/md5"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

func sayHelloName(w http.ResponseWriter, r *http.Request) {
	r.ParseForm() // 解析url传递的参数，对于POST则解析响应包的主体request body
	// 如果没有ParseForm()下面无法获取表单数据
	fmt.Println(r.Form) // 输出到服务器端的打印信息
	fmt.Println("path", r.URL.Path)
	fmt.Println("scheme", r.URL.Scheme)
	fmt.Println(r.Form["url_long"])
	for k, v := range r.Form {
		fmt.Println("key:", k)
		fmt.Println("val:", strings.Join(v, ""))
	}
	fmt.Fprintf(w, "Hello dralee!")
}

func login(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method) // 请求的方法
	if r.Method == "GET" {
		curtime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h, strconv.FormatInt(curtime, 10))
		token := fmt.Sprintf("%x", h.Sum(nil))

		t, _ := template.ParseFiles("gtpls/login.gtpl")
		log.Println(t.Execute(w, token)) // t.Execute(w, 参数），无参传入nil
	} else {
		r.ParseForm() // 调用r.Form[] 需要手动调用r.ParseForm
		// 请求的是登录数据，执行登录逻辑
		username := template.HTMLEscapeString(r.Form.Get("username")) // 防止跨站脚本 //strings.Join(r.Form["username"], "")
		password := template.HTMLEscapeString(r.Form.Get("password")) //strings.Join(r.Form["password"], "")
		token := r.Form.Get("token")
		if token != "" { // 验证token合法性

		} else { // 不存在token报错

		}
		fmt.Println("interest is ", strings.Join(r.Form["interest"], ",")) // 多值
		fmt.Println("username length: ", len(r.Form["username"][0]))
		fmt.Println("username:", username)
		fmt.Println("password:", password)
		username2 := r.FormValue("username") // 通过FormValue进行获取,formvalue会自动调用r.ParseForm, r.Form.Get()
		password2 := r.FormValue("password")
		fmt.Println("username:", username2, ",password:", password2)
		if username == "dralee" && password == "123456" {
			fmt.Fprintf(w, "welcome!,%s", username)
		} else {
			fmt.Fprintf(w, "the username not exists or the password wrong!")
		}
	}
}

/*
表单中增加enctype="multipart/form-data"
服务端调用r.ParseMultipartForm,把上传的文件存储在内存和临时文件中
使用r.FormFile获取文件句柄，然后对文件进行存储等处理。
*/
func upload(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method) // 请求方法
	if r.Method == "GET" {
		curtime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h, strconv.FormatInt(curtime, 10))
		token := fmt.Sprintf("%x", h.Sum(nil))

		t, _ := template.ParseFiles("gtpls/upload.gtpl")
		t.Execute(w, token)
	} else {
		fmt.Println("32 << 20=", 32<<20)
		r.ParseMultipartForm(32 << 20)
		file, handler, err := r.FormFile("uploadfile")
		if err != nil {
			fmt.Println(err)
			return
		}
		defer file.Close()
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./upload/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) // 此处已存在upload目录
		if err != nil {
			fmt.Println(err)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}
}

func main() {
	http.HandleFunc("/", sayHelloName)       // 设置访问路由
	http.HandleFunc("/login", login)         // 设置访问路由
	http.HandleFunc("/upload", upload)       // 设置访问路由
	err := http.ListenAndServe(":9090", nil) // 设置监听端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
